package sa.Master.Client;

import sa.Master.common.NetworkMessages.Login.*;
import sa.Master.common.NetworkMessages.Validated.*;
import sa.Master.common.Classes.*;

import java.io.*;
import java.net.*;

public class Client implements Serializable {

    public static final long serialVersionUID = 1100l;

    private Socket socket;

    /**
     * Constructor of Client.
     * 
     * Only after login is successful can the Client be successfully constructed.
     * 
     * @throws UnknownHostException on
     *      Server host cannot be resolved.
     * @throws IOException on
     *      IO Error when initializing socket.
     * @throws LoginFailureException on
     *      Server returned login failure.
     */
    public Client(String serverDomain, int serverPort, String userName, String passwordPlainText) throws UnknownHostException, IOException, LoginFailureException {
        
        // Connect to server.
        this.socket = new Socket(serverDomain, serverPort);

        // Login
        ObjectOutputStream loginRequestSendStream = null;
        ObjectInputStream loginResponseReceiveStream = null;
        LoginRequest loginRequest = new LoginRequest(userName, passwordPlainText);
        LoginResponse loginResponse = null;

        try {
            loginRequestSendStream = new ObjectOutputStream(this.socket.getOutputStream());
            loginResponseReceiveStream = new ObjectInputStream(this.socket.getInputStream());

            loginRequestSendStream.writeObject(loginRequest);
            loginResponse = (LoginResponse) loginResponseReceiveStream.readObject();

            if (loginResponse.status == LoginResponse.ReturnStatus.wrong_pwd) {
                throw new LoginFailureException("Username or password incorrect.");
            } else if (loginResponse.status == LoginResponse.ReturnStatus.blocked) {
                throw new LoginFailureException("User blocked.");
            }
        } catch (ClassNotFoundException e) {
            throw new IOException("Network error while login.");
        }
    }

    public Response getResponse(Request request) throws IOException {

        ObjectOutputStream requestSendStream = null;
        ObjectInputStream responseGetStream = null;
        Response response = null;

        try {
            requestSendStream = new ObjectOutputStream(this.socket.getOutputStream());
            responseGetStream = new ObjectInputStream(this.socket.getInputStream());

            requestSendStream.writeObject(request);
            if (!(request.action.equals("logout"))) {
                response = (Response) responseGetStream.readObject();
            }

            return response;
        } catch (IOException | ClassNotFoundException e) {
            throw new IOException("Network error!");
        }

    }
}
